import card, { cardReadCommonKey, cardRemoveEmptyRow } from "@/ts/cardData/card"
import { cardScriptRun, type cardScript } from "@/ts/cardData/cardScript"
import cardType from "@/ts/cardType/cardType"
import { reqPostCardTypeData, reqPostElementData, reqPostInitData, reqPostRoomRole, reqPostUserRole } from "@/ts/connect/requestMessage"
import RoomData, { checkRoomData } from "@/ts/roomData"
import { defineStore } from "pinia"
import { computed, ref } from "vue"
import { useServers } from "./servers"
import type { cardElement, element } from "@/ts/element"
import type roomData from "@/ts/roomData"

export const useRoom = defineStore("room", () => {
    const usingRoom = ref(new RoomData())
    const storgedRoom = ref({} as { [Index: string]: { room: roomData, time: number } })

    // /**
    //  * 添加item
    //  */
    // function pushItem(item: tableItem) {

    //     let id = Math.floor(Math.random() * 100000000).toString()
    //     while(Object.keys(usingRoom.value.tableItemList).includes(id)){
    //         id = Math.floor(Math.random() * 100000000).toString()
    //     }
    //     usingRoom.value.tableItemList[id]=item
    //     item.id= id
    //     pushZIndexList(item.id)
    // }

    // /**
    //  * 移除item
    //  */
    // function removeItem(item: tableItem) {
    //     if (item.id !== "-1") {
    //         usingRoom.value.zindexList.splice(usingRoom.value.zindexList.indexOf(item.id), 1)
    //     }
    //     delete usingRoom.value.tableItemList[item.id]
    // }
    // function updateCardItemList(cardId:string[]) {
    //     let unCheckCard=[...cardId]
    //     Object.keys(usingRoom.value.tableItemList).flatMap(key=>usingRoom.value.tableItemList[key]).filter(v=>
    //         v.data.type=='room_card'
    //     ).forEach(v=>{
    //         if(unCheckCard.includes(v.data.cardId)){
    //             unCheckCard.splice(unCheckCard.indexOf(v.data.cardId),1)
    //         }else{
    //             removeItem(v)
    //         }
    //     })
    //     for (const card of unCheckCard) {
    //         pushItem(new tableItem({cardId:card,type:"room_card"}))
    //     }
    // }
    // //zIndex 管理

    // /**
    //  * 将元素置顶
    //  */
    // function pushZIndexList(itemId: string) {

    //     if (usingRoom.value.zindexList.includes(itemId)) {
    //         usingRoom.value.zindexList.splice(usingRoom.value.zindexList.indexOf(itemId), 1)
    //     }
    //     usingRoom.value.zindexList.push(itemId)
    //     refreshZIndex()
    // }

    // /**
    //  * 刷新zindex
    //  */
    // function refreshZIndex() {
    //     for (let i = 0; i < usingRoom.value.zindexList.length; i++) {
    //         let item = usingRoom.value.tableItemList[usingRoom.value.zindexList[i]]
    //         if (item != null) {
    //             item.zindex = i * 10 + 10
    //         }
    //     }
    // }


    //card
    function getElement(id: string): element | undefined {
        return usingRoom.value.elementList[id]
    }
    function pushElement(element: element, localy?: boolean) {
        let id = Math.floor(Math.random() * 100000000).toString()
        while (Object.keys(usingRoom.value.elementList).includes(id)) {
            id = Math.floor(Math.random() * 100000000).toString()
        }
        usingRoom.value.elementList[id] = element
        element.id = id
        if (!localy) {
            synchronElement(element, id)
        }
        return id
    }
    function updateElement(id: string, element: element, localy?: boolean) {
        usingRoom.value.elementList[id] = element
        if (!localy) {
            synchronElement(element, id)
        }
    }
    function updateCardByScript(id: string | undefined, index: number[], cardScript: cardScript, data: string, keys?: string[]) {
        if (id == undefined) return
        let element = getElement(id)
        if (!element) return
        if (element.type == 'card') {

            cardScriptRun(element.card, index, cardScript, data)
            if (index.length != 0 && keys != undefined) {
                cardRemoveEmptyRow(element.card, keys, index)
            }
            synchronElement(element, id)
        }

    }
    function deleteElement(id?: string, localy?: boolean) {
        if (id == null) return false
        delete usingRoom.value.elementList[id]
        if (!localy) {
            synchronElement(undefined, id)
        }
        return true
    }

    const cardNameList = computed(() => {
        return Object.keys(usingRoom.value.elementList).filter(key => usingRoom.value.elementList[key].type == 'card').flatMap((key): { id: string, name: string } => {
            return {
                id: key,
                name: getCardName((getElement(key) as cardElement).card) ?? "未找到该卡面"
            }
        }).sort((a, b) => { return a.name.localeCompare(b.name) })
    })
    function getCardName(card: card | null) {
        if (card == null) return
        if (card.type == '') return "未选择类型的卡面"
        let cardType = usingRoom.value.cardTypeList.find(v => card.type == v.name)
        if (cardType == null) return `无法识别的${card.type}卡面,请在类型界面导入该类型`
        if (cardType.commonKeys['name'] == null) return "卡面类型没有设置共有键“name”，无法获取卡面名字，请联系类型作者处理"
        return (cardReadCommonKey(card, cardType, 'name')) || "未命名的卡"
    }

    //card-type
    function addType(cardType?: cardType, overWrite?: boolean, localy?: boolean) {
        if (cardType == undefined) return -1
        cardType = { ...cardType }
        let roomType = getType(cardType.name)
        if (roomType != null) {
            if (overWrite) {
                let index = usingRoom.value.cardTypeList.indexOf(roomType)
                usingRoom.value.cardTypeList.splice(index, 1, cardType)
                return index
            } else {
                return -1
            }
        }
        if (!localy) {
            synchronCardType(cardType, cardType.name)
        }
        return usingRoom.value.cardTypeList.push(cardType)
    }
    function deleteType(cardTypeName?: string, localy?: boolean) {
        let index = usingRoom.value.cardTypeList.flatMap(v => v.name).indexOf(cardTypeName ?? '')
        if (!localy) {
            synchronCardType(undefined, cardTypeName ?? '')
        }
        return usingRoom.value.cardTypeList.splice(index, 1).length === 1

    }
    function getType(cardTypeName?: string) {
        return usingRoom.value.cardTypeList.find(v => v.name == cardTypeName)
    }

    //room
    /**
     * 保存房间数据
     * @param room 存储的对象，置空则调用usingroom
     * @param saveName 存储对象的名称，如果名称重复则会自动添加一个“_”来防止重复，置空则自动生成基于时间的名称
     * @param overWrite 如果为true，则不会重命名同名文档，而是覆盖同名文档
     */
    function saveRoom(saveName?: string, overWrite?: boolean, room?: RoomData) {
        let newName = saveName || null
        if (newName == null) {
            newName = '未命名' + new Date().toLocaleString()
        }
        if (!overWrite) {
            while (newName in storgedRoom.value) {
                newName += '_'
            }
        }
        storgedRoom.value[newName] = {
            room: { ...(room ?? usingRoom.value) },
            time: new Date().getTime()
        }
        return newName
    }

    const roomListByTime = computed(() => {
        return Object.keys(storgedRoom.value).sort((a, b) => { return storgedRoom.value[b].time - storgedRoom.value[a].time })
    })
    /**
     * 读取房间数据
     */
    function readRoom(readName?: string) {
        if (readName == null) return
        let r = storgedRoom.value[readName].room
        importRoom({ ...r })
    }
    function getRoom(readName?: string) {

        if (readName == null) return
        let r = storgedRoom.value[readName].room
        return { ...r }
    }
    /**
     * 导入房间数据
     */
    function importRoom(room: RoomData, localy?: boolean) {
        usingRoom.value = room


        if (!localy) {
            synchronFullRoom()
        }
    }
    const defaultRoleList = computed(() => {
        return ['compare', 'everyone', ...usingRoom.value.userList.flatMap(v => "$" + v), ...usingRoom.value.roomRoleList]
    })

    function setRoomRoleList(roles: string[], localy?: boolean) {
        usingRoom.value.roomRoleList = roles
        matchRole()
        if (!localy) {
            synchronRoomRole(roles)
        }
    }
    function setUserRoleList(roles: string[], target: string, localy?: boolean) {
        usingRoom.value.userRoleList[target] = roles
        matchRole()
        if (!localy) {
            synchronUserRole(target, roles)
        }
    }
    //匹配roomRole和useRole
    function matchRole() {
        for (let user of usingRoom.value.userList) {
            usingRoom.value.userRoleList[user] = usingRoom.value.userRoleList[user]?.filter(v => usingRoom.value.roomRoleList.includes(v))
        }
    }
    function setUserList(users: string[], localy?: boolean) {
        usingRoom.value.userList = users
    }
    return {
        pushElement, addType, deleteType, getType, updateElement, deleteElement, usingRoom, storgedRoom, cardNameList, roomListByTime,
        getElement, saveRoom, readRoom, importRoom, getCardName, setRoomRoleList, setUserList,
        setUserRoleList, updateCardByScript, getRoom, defaultRoleList,matchRole
    }
}, {
    persist: {
        serializer: {
            serialize(data) {
                return JSON.stringify(data)
            },
            deserialize(data) {
                let state = JSON.parse(data)
                let roomList = state.storgedRoom
                if (typeof roomList == 'object') {
                    let result: { [Index: string]: { room: roomData, time: number } } = {}
                    for (const key of Object.keys(roomList)) {
                        if (typeof roomList[key].time == 'number' && 'room' in roomList[key]) {
                            let room = checkRoomData(roomList[key].room)
                            if (room) result[key] = {
                                room: room,
                                time: roomList[key].time
                            }
                        }
                    }
                    state.storgedCardType = result
                } else (state.storgedCardType = [])
                state.usingRoom = checkRoomData(state.usingRoom)
                return state
            },
        }
    }
})
function synchronElement(card: element | undefined, id: string) {

    //TODO 权限控制相关
    let connection = useServers().roomConnection
    if (connection) {
        connection.sendMessage(reqPostElementData(id, "*", card))
    }
}
function synchronFullRoom() {

    let connection = useServers().roomConnection
    if (connection) {
        connection.sendMessage(reqPostInitData("*"))
    }
}
function synchronCardType(cardType: cardType | undefined, id: string) {

    //TODO 权限控制相关
    let connection = useServers().roomConnection
    if (connection) {
        connection.sendMessage(reqPostCardTypeData(id, "*", cardType))
    }
}
function synchronRoomRole(role: string[]) {

    let connection = useServers().roomConnection
    if (connection) {
        connection.sendMessage(reqPostRoomRole(role))
    }
}
function synchronUserRole(target: string, role: string[]) {

    let connection = useServers().roomConnection
    if (connection) {
        connection.sendMessage(reqPostUserRole(target, role))
    }
}

